package com.boby.homecamera.helper
import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.HandlerThread
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.DefaultDataSource
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.ConcatenatingMediaSource
import androidx.media3.exoplayer.source.ProgressiveMediaSource
import com.boby.homecamera.db.VideoTable
import com.boby.homecamera.net.Api
import com.boby.lib_common.util.BLog


class SimpleVideoPlayer(
    private val context: Context,
    private val surfaceView: SurfaceView
) {
    private val TAG = "SimpleVideoPlayer"
    private val player: ExoPlayer
    private val dataSourceFactory = DefaultDataSource.Factory(context)
    @SuppressLint("UnsafeOptInUsageError")
    private val concatenatingSource = ConcatenatingMediaSource()
    private var timeListener:((index:Int,contentDuration: Long,duration:Long)->Unit)? = null
    private val handler :Handler
    private var isStart = false
    init {
        val handlerThread = HandlerThread("v_player")
        handlerThread.start()
        handler = Handler(handlerThread.looper)
        player = ExoPlayer.Builder(context)
            .setLooper(handlerThread.looper)
            .build()
        surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(holder: SurfaceHolder) {
                handler.post {
                    player.setVideoSurface(holder.surface)
                }
            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                handler.post {
                    player.setVideoSurface(null)
                }

            }

            override fun surfaceChanged(
                holder: SurfaceHolder,
                format: Int,
                width: Int,
                height: Int
            ) = Unit
        })
    }

    fun setTimeListener(listener:((index:Int,contentDuration: Long,duration:Long)->Unit)?){
        timeListener = listener
    }


    private fun startTimeListener(){
        player.addListener(object : Player.Listener {
            override fun onPlaybackStateChanged(playbackState: Int) {
                callTimeListener()
            }
            @SuppressLint("UnsafeOptInUsageError")
            override fun onPositionDiscontinuity(reason: Int) {
                // 当播放位置发生不连续变化时调用（如跳转到下一集）
                callTimeListener()
            }
        })
        handler.postDelayed(timeRunnable,1000)
    }

private val timeRunnable = object :Runnable{
    override fun run() {
        callTimeListener()
        if (isStart) handler.postDelayed(this,1000)
    }
}
    private fun callTimeListener(){
        if (isListenerTime &&
            player.isCommandAvailable(ExoPlayer.COMMAND_GET_TIMELINE)
            && player.isCommandAvailable(ExoPlayer.COMMAND_GET_TIMELINE)
            && player.isCommandAvailable(ExoPlayer.COMMAND_GET_CURRENT_MEDIA_ITEM)
        ) {
            val index = player.currentMediaItemIndex
            val currentPosition = player.currentPosition
            val contentDuration =  player.contentDuration
            if(index< 0 || contentDuration<=0 || currentPosition<0){
                return
            }
            timeListener?.invoke(index,contentDuration,currentPosition)
        }
    }


    @SuppressLint("UnsafeOptInUsageError")
    fun setVideoList(urls: List<VideoTable.Video>, ip: String, httpPort:Int,token:String?) {

        handler.post {
            val dataSourceFactory = DefaultHttpDataSource.Factory()
                .setAllowCrossProtocolRedirects(true)
                .setDefaultRequestProperties(
                    mapOf("Authorization" to "Bearer $token")
                )

            concatenatingSource.clear()
            urls.forEach { item ->
                val mediaItem = MediaItem.fromUri("${Api.getRealUrl(ip,httpPort)}/video/getvideo/?path=${item.path}")
                val source = ProgressiveMediaSource.Factory(dataSourceFactory)
                    .createMediaSource(mediaItem)

                concatenatingSource.addMediaSource(source)
            }
            if(player.isPlaying){
                player.stop()
            }

            player.setMediaSource(concatenatingSource)

        }

        if(!isStart){
            isStart = true
            startTimeListener()
        }


    }



    fun play() {
        handler.post {
            BLog.d(TAG,"play ${player.isPlaying}")
            if(player.isPlaying == false){
                player.prepare()
                player.playWhenReady = true
                isStart = true
            }
        }
    }

    fun pause() {
        handler.post {
            player.playWhenReady = false
            if(player.isPlaying == true){
                player.pause()
            }
        }

    }
    private var isListenerTime = false
    fun setListenerTime(isListenerTime: Boolean){
        this.isListenerTime = isListenerTime
    }

    fun release() {
        isStart = false
        handler.post {
            player.release()
        }

    }

    fun seekTo(mediaItemIndex:Int,positionMs: Long) {
        handler.post {
            player.seekTo(mediaItemIndex, positionMs)
        }
    }


}
